package com.lq.memo.service.impl;

import com.lq.email.entity.EmailEntity;
import com.lq.email.exception.MyException;
import com.lq.email.service.EmailService;
import com.lq.memo.calendar.LunarCalendar;
import com.lq.memo.config.MemoConfig;
import com.lq.memo.entity.Memo;
import com.lq.memo.entity.MemoTimes;
import com.lq.memo.mapper.MemoMapper;
import com.lq.memo.service.MemoService;
import com.lq.memo.service.MemoTimesService;
import com.lq.memo.util.DateUtil;
import com.lq.memo.util.IdWorker;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.awt.peer.CanvasPeer;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * @program: memo
 * @description:
 * @author: LQ
 * @create: 2021-11-05 11:09
 */
@Service
public class MemoServiceImpl implements MemoService {
    @Autowired
    private JdbcTemplate template;
    @Autowired
    private DateUtil dateUtil;
    @Autowired
    private LunarCalendar lunarCalendar;
    @Autowired
    private MemoConfig memoConfig;
    @Autowired
    EmailService emailService;

    @Autowired
    IdWorker idWorker;

    @Autowired
    MemoMapper memoMapper;
    @Autowired
    MemoTimesService memoTimesService;

    @Override
    public List<Memo> getAllMemo() {
        String sql = "select * from memo ";
        List<Memo> memoList = template.query(sql, new BeanPropertyRowMapper<>(Memo.class));
        return memoList;
    }

    /**
     * 获取距今多少天前和后的数据
     *
     * @return
     */
    @Override
    public List<Memo> getMemoList(int beforeDate, int afterDate) {
        String sql = "SELECT t.* FROM memo t WHERE str_to_date(CONCAT(date_format(SYSDATE(),'%Y'),'-',date_format(memo_date,'%m-%d')),'%Y-%m-%d') > date_sub(curdate(),interval ? day) and str_to_date(CONCAT(date_format(SYSDATE(),'%Y'),'-',date_format(memo_date,'%m-%d')),'%Y-%m-%d') < date_add(curdate(),interval ? day)";
        List<Memo> memoList = template.query(sql, new BeanPropertyRowMapper<>(Memo.class), beforeDate, afterDate);
        return memoList;
    }

    @Override
    public List<Memo> getMemoListByCalendar(Memo memo) {
        List<Object> parms = new ArrayList<>();
        StringBuilder sql = new StringBuilder(" SELECT t.* FROM memo t  where calendar_type = 0 and user_id = ? and DATE_FORMAT(memo_date,'%c-%e') in(");
        parms.add(memo.getUserId());
        List<String> lettuceCalendars = memo.getLettuceCalendars();
        StringBuilder lettuceSql = new StringBuilder();
        lettuceCalendars.forEach(lettuceCalendar -> {
            lettuceSql.append(" ?,");
            parms.add(lettuceCalendar);
        });
        if (StringUtils.isNotBlank(lettuceSql)) {
            sql.append(lettuceSql.substring(0, lettuceSql.lastIndexOf(",")));
        }
        sql.append(")");
        sql.append(" union all SELECT t.* FROM memo t  where calendar_type = 1 and user_id = ? and DATE_FORMAT(memo_date,'%c-%e') in( ");
        parms.add(memo.getUserId());
        List<String> calendars = memo.getCalendars();
        StringBuilder calendarSql = new StringBuilder();
        calendars.forEach(calendar -> {
            calendarSql.append(" ?,");
            parms.add(calendar);
        });
        if (StringUtils.isNotBlank(calendarSql)) {
            sql.append(calendarSql.substring(0, calendarSql.lastIndexOf(",")));
        }
        sql.append(")");
        List<Memo> memoList = template.query(sql.toString(), new BeanPropertyRowMapper<>(Memo.class), parms.toArray());
        return memoList;
    }

    @Override
    public void sendEmailMemo(List<Memo> memoList) throws MyException {
        //        List<MemoController> sendEmailMemoList = new ArrayList<>();
        List<MemoTimes> allMemoTimes = memoTimesService.getAllMemoTimes();
        Iterator<Memo> memoIterator = memoList.iterator();
        while (memoIterator.hasNext()) {
            Memo memo = memoIterator.next();
            String memoMonthDay = dateUtil.date2MonthDay(memo.getMemoDate());
            // 是农历
            Boolean islunar = false;
            if (memo.getCalendarType() == 0) {
                // 农历,日历需要做转换
                islunar = true;
            }
            Iterator<MemoTimes> memoTimesIterator = allMemoTimes.iterator();
            while (memoTimesIterator.hasNext()) {
                MemoTimes memoTimes = memoTimesIterator.next();
                if ((memo.getRemindTimes() & memoTimes.getDaysNo()) == memoTimes.getDaysNo()) {
                    boolean isMemoDate = isMemoDate(memoTimes.getDays(), islunar, memoMonthDay);
                    if (isMemoDate) {
                        sendEmail(memo, islunar, memoTimes.getDays());
                        continue;
                    }
                }
            }
        }
    }

    @Override
    public Integer saveOrUpdateMemo(Memo memo) {
        Integer result = 0;
        setMemoRemindTimes(memo);
        if (StringUtils.isBlank(memo.getId())) {
            result = saveMemo(memo);
        } else {
            Memo memoQuery = memoMapper.selectById(memo.getId());
            if (memoQuery != null && StringUtils.isNotBlank(memoQuery.getId())) {
                result = memoMapper.updateById(memo);
            } else {
                result = saveMemo(memo);
            }
        }
        return result;
    }

    public int saveMemo(Memo memo) {
        if (StringUtils.isBlank(memo.getId())) {
            memo.setId(idWorker.nextIdStr());
        }
        int insert = memoMapper.insert(memo);
        return insert;
    }

    /**
     * 设置提醒时间
     *
     * @param memo
     */
    @Override
    public void setMemoRemindTimes(Memo memo) {
        List<Integer> times = memo.getTimes();
        Integer countTimes = 0;
        if (times.size() > 0) {
            for (Integer time : times) {
                countTimes += time;
            }
        }
        if (countTimes > 0) {
            memo.setRemindTimes(countTimes);
        }
    }

    @Override
    public void setMemoTimes(Memo memo) {
        Integer remindTimes = memo.getRemindTimes();
        if (remindTimes <= 0) {
            return;
        }
        List<Integer> times = new ArrayList<>();
        List<MemoTimes> allMemoTimes = memoTimesService.getAllMemoTimes();
        for (MemoTimes memoTime : allMemoTimes) {
            if ((memoTime.getDaysNo() & remindTimes) == memoTime.getDaysNo()) {
                times.add(memoTime.getDaysNo());
            }
        }
        memo.setTimes(times);
    }

    private void sendEmail(Memo memo, boolean isLunar, Integer times) throws MyException {
        Date date = new Date();
        String nowMounthDay = dateUtil.getMonth(date) + "月" + dateUtil.getDate(date) + "日";
        if (isLunar) {
            nowMounthDay = lunarCalendar.getLunarCalenderMonthDay(dateUtil.getYear(date), dateUtil.getMonth(date), dateUtil.getDate(date));
        }
        EmailEntity emailEntity = new EmailEntity();
        emailEntity.setUserId(memo.getUserId().toString());
        emailEntity.setSubject("日程提醒");
        Integer month = dateUtil.getMonth(memo.getMemoDate());
        Integer day = dateUtil.getDate(memo.getMemoDate());
        //emailEntity.setText(month + "月" + day + "是" + memo.getName() + "的生日,今天是" + nowMounthDay + ",还有" + times + "天,不要忘记了哦");
        emailEntity.setText((memo.getCalendarType() == 0 ? "农历" : "") + month + "月" + day + "是" + memo.getName() + "的" + memo.getDetail() + ",今天是" + nowMounthDay + ",还有" + times + "天,不要忘记了哦");
        emailService.sendEmail(emailEntity);
    }

    /**
     * 判断是否该提示
     *
     * @param days         提醒天数
     * @param isLunar      是否农历提醒
     * @param memoMonthDay 需要提醒的日期,月日 格式MM-dd
     * @return true 需要提醒 false 不需要提醒
     */
    private boolean isMemoDate(Integer days, Boolean isLunar, String memoMonthDay) {
        Date afterDate = dateUtil.getAfterDate(days);
        String nowMonthDay = "";
        if (isLunar) {
            // 获取以后的日期
            String lunarCalenderMonthDay = lunarCalendar.getLunarCalenderMonthDay(dateUtil.getYear(afterDate), dateUtil.getMonth(afterDate), dateUtil.getDate(afterDate));
            if (lunarCalenderMonthDay.contains(memoConfig.getLeapMonthIdentifier())) {
                // 日期存在闰月标识,说明是闰月,闰月不做提示
                return false;
            }
            nowMonthDay = lunarCalenderMonthDay;
        } else {
            nowMonthDay = dateUtil.date2MonthDay(afterDate);
        }
        if (StringUtils.equals(nowMonthDay, memoMonthDay)) {
            return true;
        }
        return false;
    }

}
